package com.fuze.energy.utils;

import cn.hutool.core.util.HexUtil;
import com.fuze.energy.config.GlobalConstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * @author sepc_
 * @date 8/16/2021 15:09
 * 消息解码工具类
 */
public class MessageConvert {

    private final static Logger LOG = LoggerFactory.getLogger(MessageConvert.class);

    private static final char[] M_CHARS = "0123456789ABCDEF".toCharArray();
    private static final String M_HEX_STR = "0123456789ABCDEF";

    public MessageConvert() {
    }

    public static long longFrom8Bytes(byte[] input, int offset, boolean littleEndian) {
        long value = 0L;

        for (int count = 0; count < input.length; ++count) {
            int shift = (littleEndian ? count : 7 - count) << 3;
            value |= 255L << shift & (long) input[offset + count] << shift;
        }

        return value;
    }

    public static long bytesToInt(byte[] src, int offset) {
        long value = 0L;

        for (int i = 0; i < src.length; ++i) {
            value = (long) (src[i] & 255) << offset * (i + 1);
        }

        return value;
    }

    public static byte[] long2Bytes(long num) {
        byte[] byteNum = new byte[4];

        for (int ix = 0; ix < 4; ++ix) {
            int offset = 32 - (ix + 1) * 8;
            byteNum[ix] = (byte) ((int) (num >> offset & 255L));
        }

        return byteNum;
    }

    public static String byte2HexStr(byte[] mac, int iLen) {
        StringBuilder sb = new StringBuilder();

        for (int n = 0; n < iLen; ++n) {
            sb.append(M_CHARS[(mac[n] & 255) >> 4]);
            sb.append(M_CHARS[mac[n] & 15]);
        }

        return sb.toString().trim().toUpperCase(Locale.US);
    }

    public static byte[] hexStr2Bytes(String src) {
        src = src.trim().replace(" ", "").toUpperCase(Locale.US);
        int iLen = src.length() / 2;
        byte[] ret = new byte[iLen];

        for (int i = 0; i < iLen; ++i) {
            int m = i * 2 + 1;
            int n = m + 1;
            ret[i] = (byte) (Integer.decode("0x" + src.substring(i * 2, m) + src.substring(m, n)) & 255);
        }

        return ret;
    }

    /**
     * 定制：把编码后的消息解析为JSON数据格式
     *
     * @param message 收到的采集器消息
     * @return JSON字符串
     */
    public static Map<String, Double> parse(String message) {
        String str = HexUtil.decodeHexStr(message);
        String[] strings = str.split("[\r\n\r\n]");
        Map<String, Double> result = new HashMap<>(16);
        Arrays.asList(strings).forEach(data -> {
            String replace = data.replace("\r\n", "");
            if (!replace.equals("")) {
                if (replace.contains(",")) {
                    LOG.info("特殊的消息内容： {}", replace);
                    String[] split = replace.split(",");
                    Arrays.asList(split).forEach(s -> {
                        String[] stringSplit = s.split("=");
                        if (stringSplit.length == 2) {
                            if (stringSplit[0].equalsIgnoreCase("DHT11 TEMPERATURE")) {
                                result.put(GlobalConstance.TEMPERATURE_KEY, Double.parseDouble(stringSplit[1].replace(" C", "")));
                            }
                            if (stringSplit[0].equalsIgnoreCase("HUMIDITY")) {
                                result.put(GlobalConstance.HUMIDITY_KEY, Double.parseDouble(stringSplit[1].replace("%", "")));
                            }
                        }
                    });
                }
                LOG.info("replace = {}", replace);
                String[] split = replace.split("=");
                if (split.length == 2) {
                    if (split[0].equalsIgnoreCase(" PC0 value ")) {
                        result.put(GlobalConstance.PC0_KEY, Double.parseDouble(split[1].replace(" V", "")));
                    }
                    if (split[0].equalsIgnoreCase(" PC1 value ")) {
                        result.put(GlobalConstance.PC1_KEY, Double.parseDouble(split[1].replace(" V", "")));
                    }
                    if (split[0].equalsIgnoreCase("Mlx90614")) {
                        result.put(GlobalConstance.MLX_KEY, Double.parseDouble(split[1]));
                    }
                }
            }
        });
        LOG.info("result = {}",result);
        return result;
    }


}
